<script setup lang="ts">


import {Back, House, RefreshRight, Right, Upload} from "@element-plus/icons-vue";
import ClientUserNav from "@/components/ClientUserNav.vue";
import {onMounted, reactive, ref} from "vue";
import {useRoute} from "vue-router";
import {getNextProblemIdApi, getPrevProblemIdApi, getProblemDetailApi} from "@/api/client/problem.ts";
import {ElMessage, ElMessageBox} from "element-plus";
import JavaEditor from "@/components/JavaEditor.vue";
import router from "@/router";
import {getCodeSubmitDetailApi, listCodeSubmitsApi, submitCodeApi} from "@/api/client/code-submit.ts";
import CodeView from "@/components/CodeView.vue";
import ErrorView from "@/components/ErrorView.vue";
import {getProblemCodeApi} from "@/api/client/problem-code.ts";

onMounted(async function () {
  problemDetail.id = useRoute().query.id as any
  if (problemDetail.id) {
    await getProblemDetail()
  }
  problemCode.problemId = problemDetail.id
  await getProblemCode()
})

// 题目详情-start

const problemDetail = reactive({
  id: '',
  title: '',
  content: '',
  difficulty: 1
})

async function getProblemDetail() {
  try {
    const res = await getProblemDetailApi(problemDetail.id) as any
    problemDetail.title = res.title
    problemDetail.content = res.content
    problemDetail.difficulty = res.difficulty
  } catch (e: any) {
    ElMessage.warning(e)
  }
}

// 题目详情-end

// 切换题目-start
async function switchProblem(prevOrNext: boolean) {
  try {
    if (prevOrNext) {
      problemDetail.id = await getPrevProblemIdApi(problemDetail.id) as any
    } else {
      problemDetail.id = await getNextProblemIdApi(problemDetail.id) as any
    }

    codeSubmitList.value = []
    problemCode.problemId = problemDetail.id
    resetCodeSubmitDetail()
    handleTabChange('题目详情')
    await getProblemDetail()
    await getProblemCode()
  } catch (e: any) {
    ElMessage.warning(e)
  }
}

// 切换题目-end

// 右边的代码作答区-start

const problemCode = reactive({
  problemId: '',
  language: 1,
  userFunction: ''
})

const javaEditorRef = ref()

async function getProblemCode() {
  const res = await getProblemCodeApi(problemCode.problemId, problemCode.language) as any
  problemCode.userFunction = res.userFunction
  javaEditorRef.value.setCode(problemCode.userFunction)
}

async function resetProblemCode() {
  ElMessageBox.confirm(
      '您将放弃所有更改并初始化代码 ?',
      '操作确认',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
  )
      .then(async () => {
        await getProblemCode()
      })
}

// 右边的代码作答区-end

// 左边的标签栏切换-start

const activeTab = ref('题目详情'); // 默认激活的标签页
function handleTabChange(tabName: string) {
  activeTab.value = tabName
}

function handleTabClick(tab: any) {
  if (tab.props.name === '提交记录') {
    listCodeSubmits(); // 加载提交记录
  }
}

// 左边的标签栏切换-end

// 左侧的提交记录-start

const codeSubmitList = ref([])

async function listCodeSubmits() {
  const data = await listCodeSubmitsApi(problemDetail.id) as any;
  codeSubmitList.value = data.rows
  console.log(data.rows)
}

async function clickCodeSubmitDetail(codeSubmitId: string) {
  resetCodeSubmitDetail()
  codeSubmitDetail.id = codeSubmitId
  handleTabChange('作答详情')
  await getCodeSubmitDetail()
}

// 左侧的提交记录-end

// 头部的代码提交区-start

const submitCode = reactive({
  problemId: '',
  language: 1,
  code: ''
})

const codeSubmitDetail = reactive({
  id: '',
  language: 1,
  code: '',
  status: 0,
  message: '',
  input: '',
  output: '',
  userOutput: '',
  useTime: '',
  useMemory: '',
  createTime: ''
})

const uploadButtonTip = ref('提交')

const uploadLoading = ref(false)

function resetCodeSubmitDetail() {
  codeSubmitDetail.id = ''
  codeSubmitDetail.language = 1
  codeSubmitDetail.code = ''
  codeSubmitDetail.status = 0
  codeSubmitDetail.message = ''
  codeSubmitDetail.input = ''
  codeSubmitDetail.output = ''
  codeSubmitDetail.userOutput = ''
  codeSubmitDetail.useTime = ''
  codeSubmitDetail.useMemory = ''
  codeSubmitDetail.createTime = ''
}

async function getCodeSubmitDetail() {
  const result = await getCodeSubmitDetailApi(codeSubmitDetail.id) as any
  uploadButtonTip.value = '提交'
  uploadLoading.value = false
  codeSubmitDetail.id = result.id
  codeSubmitDetail.language = result.language
  codeSubmitDetail.code = result.code
  codeSubmitDetail.status = result.status
  codeSubmitDetail.message = result.message
  codeSubmitDetail.input = result.input
  codeSubmitDetail.output = result.output
  codeSubmitDetail.userOutput = result.userOutput
  codeSubmitDetail.useTime = result.useTime
  codeSubmitDetail.useMemory = result.useMemory
  codeSubmitDetail.createTime = result.createTime
}

async function startPollingForJudgeResult() {
  uploadButtonTip.value = '正在判题...'
  uploadLoading.value = true
  const intervalId = setInterval(async function () {
    try {
      await getCodeSubmitDetail()
      clearInterval(intervalId)
      await listCodeSubmits()
    } catch (e) {

    }
  }, 1000)
}

async function submitCodeService() {
  resetCodeSubmitDetail()
  try {
    submitCode.problemId = problemDetail.id
    submitCode.language = problemCode.language
    submitCode.code = javaEditorRef.value.code
    codeSubmitDetail.id = await submitCodeApi(submitCode.problemId, submitCode.language, submitCode.code) as any
    handleTabChange('作答详情')
    await startPollingForJudgeResult()
  } catch (e: any) {
    ElMessage.warning(e)
  }
}

// 头部的代码提交区-end

async function redirectToHome() {
  await router.push('/client/home')
}


</script>


<template>
  <div class="container">
    <div class="header">
      <div class="left">
        <el-button :icon="House" round @click="redirectToHome">首页</el-button>
        <el-button :icon="Back" round @click="switchProblem(true)">上一题</el-button>
        <el-button :icon="Right" round @click="switchProblem(false)">下一题</el-button>
      </div>
      <div class="center">
        <el-button type="success" :icon="Upload" @click="submitCodeService" :loading="uploadLoading">
          {{ uploadButtonTip }}
        </el-button>
      </div>
      <div class="right">
        <ClientUserNav/>
      </div>
    </div>
    <div class="content">
      <section>
        <d-splitter class="splitter-border" orientation="horizontal" splitBarSize="2px">
          <template v-slot:DSplitterPane>
            <d-splitter-pane
                collapseDirection="before"
                minSize="500px"
                :collapsible="true"
            >
              <div class="pane-content first">
                <el-card>
                  <el-tabs type="border-card" v-model="activeTab" @tab-click="handleTabClick">
                    <el-tab-pane name="题目详情" label="题目详情">
                      <div class="title">
                        <h2 v-text="problemDetail.title"></h2>
                      </div>
                      <div class="difficulty">
                        <el-tag type="success" v-if="problemDetail.difficulty === 1">简单</el-tag>
                        <el-tag type="warning" v-else-if="problemDetail.difficulty === 2">中等</el-tag>
                        <el-tag type="danger" v-else-if="problemDetail.difficulty === 3">困难</el-tag>
                      </div>
                      <div class="content">
                        <p v-html="problemDetail.content"></p>
                      </div>
                    </el-tab-pane>
                    <el-tab-pane name="提交记录" label="提交记录">
                      <el-table :data="codeSubmitList" style="width: 100%; height: 100%">
                        <el-table-column label="状态">
                          <template #default="scope">
                            <span v-if="scope.row.status === 0"><el-tag type="success">通过</el-tag></span>
                            <span v-else-if="scope.row.status === 1"><el-tag type="info">错误解答</el-tag></span>
                            <span v-else-if="scope.row.status === 2"><el-tag type="danger">超出内存限制</el-tag></span>
                            <span v-else-if="scope.row.status === 3"><el-tag type="danger">超出时间限制</el-tag></span>
                            <span v-else-if="scope.row.status === 4"><el-tag type="danger">编译出错</el-tag></span>
                            <span v-else-if="scope.row.status === 5"><el-tag type="warning">执行出错</el-tag></span>
                            <span v-else-if="scope.row.status === 6"><el-tag type="danger">内部出错</el-tag></span>
                          </template>
                        </el-table-column>
                        <el-table-column label="状态">
                          <template #default="scope">
                            <span v-if="scope.row.language === 1"><el-tag type="info">Java</el-tag></span>
                          </template>
                        </el-table-column>
                        <el-table-column label="执行用时">
                          <template #default="scope">
                            <span v-if="scope.row.status !== 0">N/A</span>
                            <span v-else>{{ scope.row.useTime }} ms</span>
                          </template>
                        </el-table-column>
                        <el-table-column label="消耗内存">
                          <template #default="scope">
                            <span v-if="scope.row.status !== 0">N/A</span>
                            <span v-else>{{ scope.row.useMemory }} MB</span>
                          </template>
                        </el-table-column>
                        <el-table-column prop="createTime" label="提交时间" min-width="100px"/>
                        <el-table-column label="操作">
                          <template #default="scope">
                            <el-button @click="clickCodeSubmitDetail(scope.row.id)" size="small" type="primary">
                              查看详情
                            </el-button>
                          </template>
                        </el-table-column>
                      </el-table>
                    </el-tab-pane>
                    <el-tab-pane name="作答详情" label="作答详情" :disabled="codeSubmitDetail.id === ''">
                      <div v-if="codeSubmitDetail.code === ''">
                        <el-skeleton :rows="5" animated/>
                      </div>
                      <div class="code-submit-detail" v-else>
                        <div class="top">
                          <div class="status">
                            <h3>判题结果:&nbsp;</h3>
                            <h3 v-if="codeSubmitDetail.status === 0" style="color: #2DB55D">通过</h3>
                            <h3 v-else-if="codeSubmitDetail.status === 1" style="color: #EF4743">错误解答</h3>
                            <h3 v-else-if="codeSubmitDetail.status === 2" style="color: #EF4743">超出内存限制</h3>
                            <h3 v-else-if="codeSubmitDetail.status === 3" style="color: #EF4743">超出时间限制</h3>
                            <h3 v-else-if="codeSubmitDetail.status === 4" style="color: #EF4743">编译出错</h3>
                            <h3 v-else-if="codeSubmitDetail.status === 5" style="color: #EF4743">执行出错</h3>
                            <h3 v-else-if="codeSubmitDetail.status === 6" style="color: #EF4743">内部出错</h3>
                          </div>
                          <div class="time">
                            <h3>提交时间:&nbsp;</h3>
                            <h3>{{ codeSubmitDetail.createTime.replace("T", " ") }}</h3>
                          </div>
                        </div>
                        <div class="center">
                          <div
                              v-if="codeSubmitDetail.status === 4 || codeSubmitDetail.status === 5 || codeSubmitDetail.status === 6">
                            <h3>错误信息:</h3>
                            <ErrorView :code="codeSubmitDetail.message" :key="codeSubmitDetail.message"/>
                          </div>
                          <div v-else-if="codeSubmitDetail.status === 1">
                            <div>
                              <h3>输入:</h3>
                              <ErrorView :code="codeSubmitDetail.input" :key="codeSubmitDetail.input"/>
                            </div>
                            <div style="margin-top: 20px;margin-bottom: 20px">
                              <h3>输出:</h3>
                              <ErrorView :code="codeSubmitDetail.userOutput" :key="codeSubmitDetail.userOutput"/>
                            </div>
                            <div>
                              <h3>预期结果:</h3>
                              <ErrorView :code="codeSubmitDetail.output" :key="codeSubmitDetail.output"/>
                            </div>
                          </div>
                          <div v-else-if="codeSubmitDetail.status === 0">
                            <h3>执行用时: {{ codeSubmitDetail.useTime }} ms</h3>
                            <h3>消耗内存: {{ codeSubmitDetail.useMemory }} MB</h3>
                          </div>
                        </div>
                        <div class="bottom">
                          <div class="tip">
                            <h3>代码: </h3>
                            <h3 v-if="codeSubmitDetail.language === 1">Java</h3>
                          </div>
                          <CodeView :code="codeSubmitDetail.code" :key="codeSubmitDetail.code"/>
                        </div>
                      </div>
                    </el-tab-pane>
                  </el-tabs>
                </el-card>
              </div>
            </d-splitter-pane>
            <d-splitter-pane
                :collapsible="true"
                minSize="500px">
              <div class="pane-content second">
                <el-card>
                  <div class="language">
                    <div class="left">选择语言:</div>
                    <div class="center">
                      <el-select v-model="problemCode.language" placeholder="选择语言" style="width: 200px;">
                        <el-option label="Java" :value="1"/>
                      </el-select>
                    </div>
                    <div class="right">
                      <el-tooltip content="还原到默认的代码模板" placement="bottom" effect="light">
                        <el-button :icon="RefreshRight" circle @click="resetProblemCode"/>
                      </el-tooltip>
                    </div>
                  </div>
                  <div class="answer">
                    <JavaEditor ref="javaEditorRef"/>
                  </div>
                </el-card>
              </div>
            </d-splitter-pane>
          </template>
        </d-splitter>
      </section>
    </div>
  </div>
</template>

<style scoped lang="scss">
.container {
  min-width: 1000px;

  .header {
    height: 60px;
    background-color: #F8F9FA;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .left {
      margin-left: 20px;
    }

    .right {
      margin-right: 100px;
    }
  }

  :deep(.content) {
    margin: 0 auto;
    width: 98%;

    .pane-content {
      .el-card {
        width: 100%;
        min-height: 500px;
        height: calc(100vh - 80px);
      }
    }

    .pane-content.first {
      .el-card__body {
        padding: 0;

        .el-tabs {
          height: calc(100vh - 80px);
          min-height: 500px;

          .el-tabs__content {
            padding-right: 0;

            .el-tab-pane {
              overflow: auto;
              height: 100%;
            }

            .el-tab-pane:first-child .difficulty {
              margin-bottom: 20px;
            }

            .el-tab-pane:last-child .code-submit-detail {
              .top {
                .status {
                  display: flex;
                  height: 40px;

                  h4 {
                    margin-right: 10px;
                  }
                }

                .time {
                  display: flex;
                  height: 40px;
                  margin-bottom: 20px;

                  h4 {
                    margin-right: 10px;
                  }
                }
              }

              .center {
                margin-bottom: 20px;
              }

              .bottom {
                .tip {
                  display: flex;
                }
              }
            }
          }

        }
      }
    }

    .pane-content.second {
      .el-card__body {
        height: 100%;

        .language {
          display: flex;
          align-items: center;
          margin-bottom: 20px;

          .center {
            margin-left: 20px;
            margin-right: 20px;
          }
        }

        .answer {
          height: calc(99% - 50px);
        }
      }
    }
  }


  .splitter-border {
    border: 1px solid #dfe1e6;
  }
}
</style>
